{
 "cells": [
  {
   "attachments": {},
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "# Reaction Names\n",
    "\n",
    "PyNE aims to provide a canonical form for reaction names while also ensuring compatibility with external spellings, such as [MT numbers](https://t2.lanl.gov/nis/endf/mts.html). Similar to the `nucname` module, the canonical form of a reaction is represented by an integer obtained using the `id()` function, while the human-readable name can be obtained using the `name()` function.\n",
    "\n",
    "**Reaction Names:** The reaction names are chosen as strings that comply with the rules for valid variable names in most programming languages, including Python and C/C++. This approach, known as *natural naming*, establishes a namespace for reactions. Consequently, all reaction names must adhere to the regular expression ``[A-Za-z_][A-Za-z0-9_]*``.\n",
    "\n",
    "For instance, the elastic scattering cross section is represented by the name *elastic*, while the pair production reaction is denoted as *pair_prod*.\n",
    "\n",
    "A number of patterns dictate how a reaction should be named. Foremost among these are particle names. Where required, \"z\" is a variable for any incident particle. The following table displays particle types and their names:\n",
    "\n",
    "| particle  | name (z) |\n",
    "|-----------|:--------:|\n",
    "| neutron   | n        |\n",
    "| proton    | p        |\n",
    "| deuterium | d        |\n",
    "| tritium   | t        |\n",
    "| Helium-3  | He3      |\n",
    "| alpha     | a        |\n",
    "| gamma     | gamma    |\n",
    "\n",
    "The term used to describe a reaction that generates a neutron and a proton is \"np\". When multiple particles of the same type are produced, the number comes before the particle type. For instance, \"n2p\" represents one neutron and two protons. However, if the name would begin with a number, it is prefixed with `z_` to indicate the number of incident particles. For example, \"z_2n\" denotes a reaction yielding two neutrons (as \"2n\" is not a valid variable name in most programming languages).\n",
    "\n",
    "Additionally, if a reaction name ends with `_[0-9]+` (underscore followed by digits), it signifies that the nucleus remains in the nth excited state after the interaction. For instance, \"n_0\" produces a neutron while leaving the nucleus in the ground state, while \"n_1\" produces a neutron with the nucleus in the first excited state, and so on. Conversely, \"_continuum\" implies that the nucleus is in an energy state within the continuum.\n",
    "\n",
    "In cases where a reaction name begins with `erel_`, it indicates the energy release from the reaction named without the `erel_` prefix. For example, `erel_p` represents the energy release from proton emission.\n",
    "\n",
    "**Reaction IDs:** Instead of using variable-length strings to define all possible reactions in a partially physically meaningful way, it is more advantageous to have a fixed-width format for storage purposes. For this reason, each reaction name is assigned a unique, unsigned 32-bit integer as an identifier. These identifiers are computed using a custom hash function that reserves space for MT numbers, ensuring that values below 1000 are not produced. It is highly recommended to use these reaction identifiers for performance-critical tasks instead of relying on the reaction names themselves.\n",
    "\n",
    "**Reaction Labels:** Reaction labels serve as concise, easily understandable strings for human consumption. Unlike the reaction names, these labels are not constrained by naming convention restrictions. Moreover, they do not need to be unique, offering flexibility in their application. The provision of reaction labels is primarily intended to enhance the user interface experience by facilitating intuitive interaction with the reactions.\n",
    "\n",
    "**Reaction Docstrings:** Similar to labels, reactions are accompanied by documentation strings that provide a brief description of the reaction in a sentence or two. These docstrings offer helpful and informative details about each reaction, serving as a valuable resource for understanding their purpose and behavior. They are particularly useful in contexts such as tool-tips within user interfaces, where users can access additional information about the reactions as needed.\n",
    "\n",
    "**Other Canonical Forms:** This module offers mappings that establish connections between alternative canonical forms of reactions and the naming conventions and IDs employed in this context. Among these forms, one of the most widely recognized is the MT numbers. MT numbers represent a specific subset of the reactions utilized within this framework. For more detailed information, additional resources can be found at NNDC, NEA, T2, and JAEA, which provide comprehensive insights into these canonical forms and their applications.\n",
    "\n",
    "The rxname module provides a comprehensive set of functions for computing or retrieving reaction names and their associated data as described above. These functions offer various interfaces, allowing lookup based on different criteria such as name, ID, MT number, a string of ID, or a string of MT number.\n",
    "\n",
    "In addition to the primary lookup methods, the module also supports alternative names or abbreviations for reactions. For example, \"tot\" or \"abs\" can be used to retrieve the corresponding names \"total\" or \"absorption\" respectively. Similarly, spelling out particle names such as \"alpha\" or \"duet\" will return their respective abbreviations \"a\" or \"d\". The module maintains an `altnames` variable containing a comprehensive list of all alternative names for reference.\n",
    "\n",
    "Furthermore, some reactions can be inferred based on the nuclide before and after the reaction. For instance, if an incident neutron strikes U-235 and Th-232 is produced, it can be assumed that an alpha production reaction has occurred. As a result, many functions in the rxname module accept parameters for the from nuclide, to nuclide, and the incident particle type (defaulting to \"n\" for neutron). It's worth noting that the incident particle type can also be specified as \"decay\" to indicate a radioactive decay event.\n",
    "\n",
    "Overall, the rxname module offers a versatile range of functions that facilitate reaction name lookup and provide additional flexibility through alternate names, abbreviations, and inferred reactions based on nuclide information."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 1,
   "metadata": {},
   "outputs": [],
   "source": [
    "from pyne import rxname"
   ]
  },
  {
   "attachments": {},
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Each reaction name has a unique id number. These are defined on the range from `1000 < id <= 2^32` so that they do not conflict with MT numbers."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 2,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "ID for total: 1313192322\n",
      "ID for proton production: 1104\n",
      "ID for elastic scattering: 3556114565\n",
      "ID for absorption: 3163131457\n"
     ]
    }
   ],
   "source": [
    "print(f'ID for total:', rxname.id(\"total\"))\n",
    "\n",
    "# MT number for production of a proton is 103\n",
    "print(f'ID for proton production:', rxname.id(103))\n",
    "\n",
    "# MT number for elastic scattering cross section for incident particles is 2\n",
    "print(f'ID for elastic scattering:', rxname.id(2))\n",
    "\n",
    "print(f'ID for absorption:', rxname.id(\"abs\"))"
   ]
  },
  {
   "attachments": {},
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "The string names are also unique:"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 3,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "total\n",
      "p\n",
      "absorption\n"
     ]
    }
   ],
   "source": [
    "print(rxname.name(\"total\"))\n",
    "print(rxname.name(103))    # MT number for proton production\n",
    "print(rxname.name(\"abs\"))  # an abbreviation for absorption"
   ]
  },
  {
   "attachments": {},
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Each reaction also has meta-data that is stored as short 'labels' and longer documentation strings."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 4,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "(z,p)\n",
      "(z,p) Production of p\n"
     ]
    }
   ],
   "source": [
    "print(rxname.label('p'))\n",
    "print(rxname.doc('p'))"
   ]
  },
  {
   "attachments": {},
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Where possible, MT numbers may be looked up."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 5,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "2\n",
      "103\n"
     ]
    }
   ],
   "source": [
    "print(rxname.mt('elastic'))\n",
    "print(rxname.mt('p'))"
   ]
  },
  {
   "attachments": {},
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Finally, nuclides themselves may also be used to look up reactions."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 6,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "'absorption'"
      ]
     },
     "execution_count": 6,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "# From -> to\n",
    "rxname.name(\"U235\", \"U236\")"
   ]
  },
  {
   "attachments": {},
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "The interface includes a parameter called *incident particle type* (`z`), which is initially set to `n` for neutrons but can be changed to any of the particle types mentioned earlier."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 7,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "'absorption'"
      ]
     },
     "execution_count": 7,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "rxname.name(\"U235\", \"Np236\", \"p\")"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 8,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "'p'"
      ]
     },
     "execution_count": 8,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "rxname.name(922350000, 912350000)"
   ]
  },
  {
   "attachments": {},
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Additionally, the interface provides two functions called `parent()` and `child()`. These functions allow you to determine the parent or child nuclide based on a given nuclide, the reaction, and the incident particle type."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 9,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "922350000"
      ]
     },
     "execution_count": 9,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "rxname.parent(\"U236\", 'abs')"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 10,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "932360000"
      ]
     },
     "execution_count": 10,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "rxname.child(\"U235\", 'abs', 'p')"
   ]
  }
 ],
 "metadata": {
  "kernelspec": {
   "display_name": "Python 3",
   "language": "python",
   "name": "python3"
  },
  "language_info": {
   "codemirror_mode": {
    "name": "ipython",
    "version": 3
   },
   "file_extension": ".py",
   "mimetype": "text/x-python",
   "name": "python",
   "nbconvert_exporter": "python",
   "pygments_lexer": "ipython3",
   "version": "3.11.2"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 1
}
